protected $rgwS3AccessKey;
/** @var string S3 authentication key (RADOS Gateway) */
protected $rgwS3SecretKey;
+ /** @var array Additional users (account:user) to open read permissions for */
+ protected $readUsers;
+ /** @var array Additional users (account:user) to open write permissions for */
+ protected $writeUsers;
/** @var BagOStuff */
protected $srvCache;
/**
* @see FileBackendStore::__construct()
- * Additional $config params include:
+ * @param array $config Params include:
* - swiftAuthUrl : Swift authentication server URL
* - swiftUser : Swift user used by MediaWiki (account:username)
* - swiftKey : Swift authentication key for the above user
* This is used for generating expiring pre-authenticated URLs.
* Only use this when using rgw and to work around
* http://tracker.newdream.net/issues/3454.
+ * - readUsers : Swift users that should have read access (account:username)
+ * - writeUsers : Swift users that should have write access (account:username)
*/
public function __construct( array $config ) {
parent::__construct( $config );
} else {
$this->srvCache = new EmptyBagOStuff();
}
+ $this->readUsers = isset( $config['readUsers'] )
+ ? $config['readUsers']
+ : [];
+ $this->writeUsers = isset( $config['writeUsers'] )
+ ? $config['writeUsers']
+ : [];
}
public function getFeatures() {
$stat = $this->getContainerStat( $fullCont );
if ( is_array( $stat ) ) {
+ $readUsers = array_merge( $this->readUsers, [ $this->swiftUser ] );
+ $writeUsers = array_merge( $this->writeUsers, [ $this->swiftUser ] );
// Make container private to end-users...
$status->merge( $this->setContainerAccess(
$fullCont,
- [ $this->swiftUser ], // read
- [ $this->swiftUser ] // write
+ $readUsers,
+ $writeUsers
) );
} elseif ( $stat === false ) {
$status->fatal( 'backend-fail-usable', $params['dir'] );
$stat = $this->getContainerStat( $fullCont );
if ( is_array( $stat ) ) {
+ $readUsers = array_merge( $this->readUsers, [ $this->swiftUser, '.r:*' ] );
+ $writeUsers = array_merge( $this->writeUsers, [ $this->swiftUser ] );
+
// Make container public to end-users...
$status->merge( $this->setContainerAccess(
$fullCont,
- [ $this->swiftUser, '.r:*' ], // read
- [ $this->swiftUser ] // write
+ $readUsers,
+ $writeUsers
) );
} elseif ( $stat === false ) {
$status->fatal( 'backend-fail-usable', $params['dir'] );
/** @noinspection PhpUnusedLocalVariableInspection */
$ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
- $this->logger->error( __METHOD__ . ": $path was not stored with SHA-1 metadata." );
+ $this->logger->error( __METHOD__ . ": {path} was not stored with SHA-1 metadata.",
+ [ 'path' => $path ] );
$objHdrs['x-object-meta-sha1base36'] = false;
}
}
- $this->logger->error( __METHOD__ . ": unable to set SHA-1 metadata for $path" );
+ $this->logger->error( __METHOD__ . ': unable to set SHA-1 metadata for {path}',
+ [ 'path' => $path ] );
return $objHdrs; // failed
}
*
* @param string $fullCont Resolved container name
* @param string $dir Resolved storage directory with no trailing slash
- * @param string|null $after Resolved container relative path to list items after
+ * @param string|null &$after Resolved container relative path to list items after
* @param int $limit Max number of items to list
* @param array $params Parameters for getDirectoryList()
* @return array List of container relative resolved paths of directories directly under $dir
*
* @param string $fullCont Resolved container name
* @param string $dir Resolved storage directory with no trailing slash
- * @param string|null $after Resolved container relative path of file to list items after
+ * @param string|null &$after Resolved container relative path of file to list items after
* @param int $limit Max number of items to list
* @param array $params Parameters for getDirectoryList()
* @return array List of resolved container relative paths of files under $dir
* @return StatusValue[]
*/
protected function doExecuteOpHandlesInternal( array $fileOpHandles ) {
- /** @var $statuses StatusValue[] */
+ /** @var StatusValue[] $statuses */
$statuses = [];
$auth = $this->getAuthentication();
* (lists are truncated to 10000 item with no way to page), and is just a performance risk.
*
* @param string $container Resolved Swift container
- * @param array $readGrps List of the possible criteria for a request to have
+ * @param array $readUsers List of the possible criteria for a request to have
* access to read a container. Each item is one of the following formats:
* - account:user : Grants access if the request is by the given user
* - ".r:<regex>" : Grants access if the request is from a referrer host that
* Setting this to '*' effectively makes a container public.
* -".rlistings:<regex>" : Grants access if the request is from a referrer host that
* matches the expression and the request is for a listing.
- * @param array $writeGrps A list of the possible criteria for a request to have
+ * @param array $writeUsers A list of the possible criteria for a request to have
* access to write to a container. Each item is of the following format:
* - account:user : Grants access if the request is by the given user
* @return StatusValue
*/
- protected function setContainerAccess( $container, array $readGrps, array $writeGrps ) {
+ protected function setContainerAccess( $container, array $readUsers, array $writeUsers ) {
$status = $this->newStatus();
$auth = $this->getAuthentication();
'method' => 'POST',
'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth ) + [
- 'x-container-read' => implode( ',', $readGrps ),
- 'x-container-write' => implode( ',', $writeGrps )
+ 'x-container-read' => implode( ',', $readUsers ),
+ 'x-container-write' => implode( ',', $writeUsers )
]
] );
if ( $rcode != 204 && $rcode !== 202 ) {
$status->fatal( 'backend-fail-internal', $this->name );
- $this->logger->error( __METHOD__ . ': unexpected rcode value (' . $rcode . ')' );
+ $this->logger->error( __METHOD__ . ': unexpected rcode value ({rcode})',
+ [ 'rcode' => $rcode ] );
}
return $status;
// @see SwiftFileBackend::setContainerAccess()
if ( empty( $params['noAccess'] ) ) {
- $readGrps = [ '.r:*', $this->swiftUser ]; // public
+ $readUsers = array_merge( $this->readUsers, [ '.r:*', $this->swiftUser ] ); // public
} else {
- $readGrps = [ $this->swiftUser ]; // private
+ $readUsers = array_merge( $this->readUsers, [ $this->swiftUser ] ); // private
}
- $writeGrps = [ $this->swiftUser ]; // sanity
+
+ $writeUsers = array_merge( $this->writeUsers, [ $this->swiftUser ] ); // sanity
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( [
'method' => 'PUT',
'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth ) + [
- 'x-container-read' => implode( ',', $readGrps ),
- 'x-container-write' => implode( ',', $writeGrps )
+ 'x-container-read' => implode( ',', $readUsers ),
+ 'x-container-write' => implode( ',', $writeUsers )
]
] );
if ( $code == 401 ) { // possibly a stale token
$this->srvCache->delete( $this->getCredsCacheKey( $this->swiftUser ) );
}
- $this->logger->error(
- "HTTP $code ($desc) in '{$func}' (given '" . FormatJson::encode( $params ) . "')" .
- ( $err ? ": $err" : "" )
- );
+ $msg = "HTTP {code} ({desc}) in '{func}' (given '{params}')";
+ $msgParams = [
+ 'code' => $code,
+ 'desc' => $desc,
+ 'func' => $func,
+ 'req_params' => FormatJson::encode( $params ),
+ ];
+ if ( $err ) {
+ $msg .= ': {err}';
+ $msgParams['err'] = $err;
+ }
+ $this->logger->error( $msg, $msgParams );
}
}
*
* @param string $container Resolved container name
* @param string $dir Resolved path relative to container
- * @param string $after
+ * @param string &$after
* @param int $limit
* @param array $params
* @return Traversable|array